#include"enclave.h"
#include"skiplist_enclave_u.h"
#include<set>
#include<ctime>
#include<cstdio>
#include<random>
#include<iostream>
#include<forward_list>
#include <iomanip>
#include <fstream>
#include <cstdlib>

using namespace std;
int _w;
const size_t COPY_SIZE=4*(sizeof(uint32_t));
char tmpresult[512];
char* transferFromString(string src) {
	int siz = src.length();
	if (siz < 512) {
		for (int i = 0; i <= siz; i++) {
			tmpresult[i] = src[i];
		}
	}
	return tmpresult;
}

int main(int argc, char* argv[]) { //对比跳表与STL的set
	cc_enclave_t eid= {};
	cc_enclave_result_t ret;
	char *path = transferFromString(PATH);
	_w=argc;
	ret = cc_enclave_create(path, AUTO_ENCLAVE_TYPE, 0, SECGEAR_DEBUG_FLAG, NULL, 0, &eid);
	if (ret != CC_SUCCESS) {
		printf("ERR: %#x ,failed to create enclave.\n", ret);
		return -1;
	}
    
	int n;
	// 根据数据集进行操作
    double L_insert_mean=0,S_insert_mean=0,FL_insert_mean=0;
    double L_find_mean=0,S_find_mean=0,FL_find_mean=0;
    double L_delete_mean=0,S_delete_mean=0,FL_delete_mean=0;
    // 对0～10000的数进行操作
    double L_insert_mean1=0,S_insert_mean1=0,FL_insert_mean1=0;
    double L_find_mean1=0,S_find_mean1=0,FL_find_mean1=0;
    double L_delete_mean1=0,S_delete_mean1=0,FL_delete_mean1=0;

    uint32_t x[2];
	
	for(int _c=1;_c<=10;_c++) // 十次循环取平均
    {
        double insert_L=0,insert_S=0,insert_FL=0;
        double find_L=0,find_S=0,find_FL=0;
        double delete_L=0, delete_S=0,delete_FL=0;
        // ifstream inFile,inFile1,inFile2;
        FILE *inFile,*inFile1,*inFile2;
        // 根据数据集进行插入
        //inFile.open("/Users/tangxin/Desktop/text_50000.txt");
        // inFile.open("/Users/tangxin/Desktop/text_10000.txt");  // 数据集中为乱序1～10000的不重复数据
        // inFile.open(argv[1]);  // 数据集中为乱序1～10000的不重复数据
        inFile=fopen(argv[1],"r");  // 数据集中为乱序1～10000的不重复数据
        if (!inFile) {
            cout << "Unable to open file";
            exit(1); // terminate with error
        }

        _w=fscanf(inFile,"%d",&n);
        // while (inFile >> x) {
        for(int i=0;i<n;i++){
            _w=fscanf(inFile,"%u",&x[0]);
            double clk_1=clock();
            // L.insert(x);
            Linsert(&eid,x);
            double clk_2=clock();
            // S.insert(x);
            Sinsert(&eid,x);
            double clk_3=clock();
            // FL.push_front(x);
            // FL.sort();
            Finsert(&eid,x);
            double clk_4=clock();
            //printf("%u ",x);
            insert_L+=clk_2-clk_1;
            insert_S+=clk_3-clk_2;
            insert_FL+=clk_4-clk_3;
        }
        fclose(inFile);
        // inFile.close();
//        printf("\n跳表插入:%lfs\n",insert_L/CLOCKS_PER_SEC);
//        printf("set插入:%lfs\n",insert_S/CLOCKS_PER_SEC);
//        printf("链表插入:%lfs\n",insert_FL/CLOCKS_PER_SEC);
        L_insert_mean +=insert_L;
        FL_insert_mean+=insert_FL;
        S_insert_mean+=insert_S;
        
        // 根据数据集进行查找
        //inFile1.open("/Users/tangxin/Desktop/text_50000.txt");
        // inFile1.open("/Users/tangxin/Desktop/text_10000.txt");
        // inFile1.open(argv[1]);
        inFile1=fopen(argv[1],"r");
        if (!inFile1) {
            cout << "Unable to open file";
            exit(1); // terminate with error
        }

        for(int i=0;i<n;i++){
            _w=fscanf(inFile1,"%u",&x[0]);
        // while (inFile1 >> x) {
            double clk_5=clock();
            // L.find(x);
            Lfind(&eid,x);
            double clk_6=clock();
            // S.find(x);
            Sfind(&eid,x);
            double clk_7=clock();
            // std::find(FL.begin(), FL.end(), x);
            Ffind(&eid,x);
            double clk_8=clock();
            //printf("%u ",x);
            find_L+=clk_6-clk_5;
            find_S+=clk_7-clk_6;
            find_FL+=clk_8-clk_7;
        }
        fclose(inFile1);
        // inFile1.close();
//        printf("\n跳表查找:%lfs\n",find_L/CLOCKS_PER_SEC);
//        printf("set查找:%lfs\n",find_S/CLOCKS_PER_SEC);
//        printf("链表查找:%lfs\n",find_FL/CLOCKS_PER_SEC);
        L_find_mean+=find_L;
        S_find_mean+=find_S;
        FL_find_mean+=find_FL;
        
        // 根据数据集进行删除,text_10000或text_50000
        //inFile2.open("/Users/tangxin/Desktop/text_50000.txt");
        // inFile2.open("/Users/tangxin/Desktop/text_10000.txt"); // 修改数据集时要修改MAX_LEVEL
        // inFile2.open(argv[1]); // 修改数据集时要修改MAX_LEVEL
        inFile2=fopen(argv[1],"r");
        if (!inFile2) {
            cout << "Unable to open file";
            exit(1); // terminate with error
        }

        for(int i=0;i<n;i++){
            _w=fscanf(inFile2,"%u",&x[0]);
        // while (inFile2 >> x) {
            double clk_9=clock();
            // L.remove(x);
            Lremove(&eid,x);
            double clk_10=clock();
            // S.erase(x);
            Sremove(&eid,x);
            double clk_11=clock();
            // FL.remove(x);
            Fremove(&eid,x);
            // std::find(FL.begin(), FL.end(), x);
            //FL.sort();
            double clk_12=clock();
            //printf("%u ",x);
            delete_L+=clk_10-clk_9;
            delete_S+=clk_11-clk_10;
            delete_FL+=clk_12-clk_11;
        }
        fclose(inFile2);
        // inFile2.close();
//        printf("\n跳表查找:%lfs\n",find_L/CLOCKS_PER_SEC);
//        printf("set查找:%lfs\n",find_S/CLOCKS_PER_SEC);
//        printf("链表查找:%lfs\n",find_FL/CLOCKS_PER_SEC);
        L_delete_mean+=delete_L;
        S_delete_mean+=delete_S;
        FL_delete_mean+=delete_FL;
        
        inFile=fopen(argv[1],"r");  // 数据集中为乱序1～10000的不重复数据
        if (!inFile) {
            cout << "Unable to open file";
            exit(1); // terminate with error
        }

        _w=fscanf(inFile,"%d",&n);
        fclose(inFile);
        // 对0～10000的数进行操作
        //插入
        double clk1 = clock();
        for(int i=n;i>=1;i--){
            x[0]=i;
            Linsert(&eid,x);
        }
       //for(int i=50000;i>=1;i--)
            // L1.insert(i);
            
        double clk2 = clock();
        for(int i=n;i>=1;i--){
            x[0]=i;
            Sinsert(&eid,x);
        }
        //for(int i=50000;i>=1;i--)
            // S1.insert(i);
            
        double clk3 = clock();
        //for(int i=50000;i>=1;i--)
        for(int i=n;i>=1;i--){
            x[0]=i;
            // FL1.push_front(i);
            // FL1.sort();
			Finsert(&eid,x);
		}
        double clk4 = clock();
        L_insert_mean1+=clk2-clk1;
        S_insert_mean1+=clk3-clk2;
        FL_insert_mean1+=clk4-clk3;
        //查找
        double clk5 = clock();
       for(int i=n;i>=1;i--){
            x[0]=i;
            Lfind(&eid,x);
        }
       //for(int i=50000;i>=1;i--)
            // L1.find(i);
            // Lfind(&eid,(uint32_t)i);
        double clk6 = clock();
        for(int i=n;i>=1;i--){
            x[0]=i;
            Sfind(&eid,x);
        }
        //for(int i=50000;i>=1;i--)
            // S1.find(i);
            // Sfind(&eid,(uint32_t)i);
        double clk7 = clock();
        for(int i=n;i>=1;i--){
            x[0]=i;
            Ffind(&eid,x);
        }
        //for(int i=50000;i>=1;i--)
            // std::find(FL1.begin(), FL1.end(), i);
            // Ffind(&eid,(uint32_t)i);
        double clk8 = clock();
        L_find_mean1+=clk6-clk5;
        S_find_mean1+=clk7-clk6;
        FL_find_mean1+=clk8-clk7;
        // 删除
        double clk9 = clock();
       for(int i=n;i>=1;i--){
            x[0]=i;
            Lremove(&eid,x);
        }
        //for(int i=50000;i>=1;i--)
            // L1.remove(i);
            // Lremove(&eid,(uint32_t)i);
        double clk10 = clock();
        for(int i=n;i>=1;i--){
            x[0]=i;
            Sremove(&eid,x);
        }
        //for(int i=50000;i>=1;i--)
            // S1.erase(i);
            // Sremove(&eid,(uint32_t)i);
        double clk11 = clock();
        for(int i=n;i>=1;i--){
            x[0]=i;
            Fremove(&eid,x);
        }
        //for(int i=50000;i>=1;i--)
            // FL1.remove(i);
            // Fremove(&eid,(uint32_t)i);
        double clk12 = clock();
        L_delete_mean1+=clk10-clk9;
        S_delete_mean1+=clk11-clk10;
        FL_delete_mean1+=clk12-clk11;
    }
    printf("根据数据集进行插入：\n");
    printf("跳表:%lfs, set:%lfs, 链表:%lfs\n",L_insert_mean/10/CLOCKS_PER_SEC,S_insert_mean/10/CLOCKS_PER_SEC,FL_insert_mean/10/CLOCKS_PER_SEC);
    printf("根据数据集进行查找：\n");
    printf("跳表:%lfs, set:%lfs, 链表:%lfs\n",L_find_mean/10/CLOCKS_PER_SEC,S_find_mean/10/CLOCKS_PER_SEC,FL_find_mean/10/CLOCKS_PER_SEC);
    printf("根据数据集进行删除：\n");
    printf("跳表:%lfs, set:%lfs, 链表:%lfs\n",L_delete_mean/10/CLOCKS_PER_SEC,S_delete_mean/10/CLOCKS_PER_SEC,FL_delete_mean/10/CLOCKS_PER_SEC);
    printf("对0～%d的数据按序进行插入：\n",n);
    printf("跳表:%lfs, set:%lfs, 链表:%lfs\n",L_insert_mean1/10/CLOCKS_PER_SEC,S_insert_mean1/10/CLOCKS_PER_SEC,FL_insert_mean1/10/CLOCKS_PER_SEC);
    printf("对0～%d的数据按序进行查找：\n",n);
    printf("跳表:%lfs, set:%lfs, 链表:%lfs\n",L_find_mean1/10/CLOCKS_PER_SEC,S_find_mean1/10/CLOCKS_PER_SEC,FL_find_mean1/10/CLOCKS_PER_SEC);
    printf("对0～%d的数据按序进行删除：\n",n);
    printf("跳表:%lfs, set:%lfs, 链表:%lfs\n",L_delete_mean1/10/CLOCKS_PER_SEC,S_delete_mean1/10/CLOCKS_PER_SEC,FL_delete_mean1/10/CLOCKS_PER_SEC);

	if (CC_SUCCESS != cc_enclave_destroy(&eid)) {
		return -1;
	}
	return 0;
}
